
/**
 * itbooking系统平台<br/>
 * com.itbooking.util<br/>
 * ProjectAutoUtil.java<br/>
 * 创建人:mofeng <br/>
 * 时间：2018年9月25日-下午10:21:55 <br/>
 * 2018itbooking-版权所有<br/>
 */
package com.xq.auto;

import com.xq.auto.tool.*;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.*;

/**
 * 自动构建类
 * ProjectAutoUtil<br/>
 * 创建人:xuke<br/>
 * 时间：2018年9月25日-下午10:21:55 <br/>
 *
 * @version 1.0.0<br />
 */
public class AutoProjectUtil2 {

    //数据库信息
    private static String DB = "mzct_db";
    private static String IP = "127.0.0.1:3306";
    private static String UNAME = "admin";
    private static String PWD = "123456";
    //数据体对应的实体
    private static String beanModel = "News";
    // 数据库对应的表
    private static String tablename = "kss_news";
    private static Integer isCategory = 1;
    private static Integer isEditor = 1;
    private static Integer isUpload = 1;

    private static String model = beanModel.toLowerCase();
    private static String author = "ljh";
    private static String url = "https://www.kuangstudy.com";
    private static String url2 = "https://space.bilibili.com/490711252";
    private static String description2 = "新闻";
    private static String description = description2 + "管理";
    private static String phone = "19805289976";
    private static String datetime = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date());

    //获取当前项目路径
    private static String projectPath = System.getProperty("user.dir");
    private static String rootPackage = "com.xq";
    private static String entityPackage = rootPackage + ".entity";
    private static String servicePackage = rootPackage + ".service."+model;
    private static String controllerPackage = rootPackage + ".controller."+model;
    private static String mapperPackage = rootPackage + ".mapper";
    private static String voPackage = rootPackage + ".vo";


    public static void main(String[] args) throws IOException {

        String projectName = projectPath;
        String entityPath =  "/src/main/java/" + replaceLine(entityPackage);
        String mapperPath =  "/src/main/java/" + replaceLine(mapperPackage);
        String servicePath =  "/src/main/java/" + replaceLine(servicePackage);
        String voPath =  "/src/main/java/" + replaceLine(voPackage);
        String controllerPath =  "/src/main/java/" + replaceLine(controllerPackage);
        String mapperxmlPath =  "/src/main/resources/mapper/";

        String listPagePath =  "/src/main/resources/templates/"+model;
        String addPagePath =  "/src/main/resources/templates/"+model;


        List<Map<String, String>> maps = loadTable();
        // entity生成
        loadTemplate(maps, entityPath, beanModel + ".java", "pojo.tml");
        // mapper生成
        loadTemplate(maps, mapperPath, beanModel + "Mapper.java", "mapper.tml");
        // mapperxml生成
        loadTemplate(maps, mapperxmlPath, beanModel + "Mapper.xml", "mapperxml.tml");
        // service生成
        loadTemplate(maps, servicePath, "I" + beanModel + "Service.java", "service.tml");
        // serviceimpl生成
        loadTemplate(maps, servicePath, beanModel + "ServiceImpl.java", "serviceImpl.tml");
        // vo生成
        loadTemplate(maps, voPath, beanModel + "Vo.java", "vo.tml");
        // controller生成
        loadTemplate(maps, controllerPath, beanModel + "Controller.java", "controller.tml");

        // controller生成
        loadTemplate(maps, listPagePath, "list.html", "list.tml");
        // controller生成
        loadTemplate(maps, addPagePath,   "add.html", "add.tml");

    }

    /*
    获得某表中所有字段的注释
    * @param tableName
    * @return
            * @throws Exception
    */
    public static Map<String, String> getColumnCommentByTableName(String tableName) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            Map<String, String> map = new HashMap<>();
            conn = getMySQLConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery("show full columns from " + tableName);
            System.out.println("【" + tableName + "】");
            while (rs.next()) {
                map.put(rs.getString("Field"), rs.getString("Comment"));
            }
            return map;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        } finally {
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }


    public static void loadTemplate(List<Map<String, String>> maps, String packagename, String filename, String template) {
        try {
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
            // 指定模板文件从何处加载的数据源，这里设置成一个文件目录。
            cfg.setDirectoryForTemplateLoading(new File(projectPath + "/templates"));
            // 指定模板如何检索数据模型，这是一个高级的主题了… // 但先可以这么来用：
            cfg.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_28));

            // 创建根哈希表
            Map root = new HashMap();
            // 在根中放入字符串"user"
            root.put("tablename", tablename);
            root.put("author", author);
            root.put("beanModel", beanModel);
            root.put("model", model);
            root.put("phone", phone);
            root.put("basePath", "${basePath}");
            root.put("rootPath", "${rootPath}");


            root.put("rootPackage", rootPackage);
            root.put("entityPackage", entityPackage);
            root.put("controllerPackage", controllerPackage);
            root.put("servicePackage", servicePackage);
            root.put("voPackage", voPackage);
            root.put("mapperPackage", mapperPackage);

            root.put("datetime", datetime);
            root.put("url", url);
            root.put("url2", url2);
            root.put("description2", description2);
            root.put("description", description);
            root.put("fields", maps);
            root.put("kuohao", new AddKuohu());
            root.put("kuohao2", new AddKuohu2());
            root.put("kuohao3", new AddKuohu3());
            root.put("listtag", new ListTag());
            root.put("Include", new IncludeTagMethod());

            root.put("dbname",DB);
            root.put("ip",IP);
            root.put("dbusername",UNAME);
            root.put("dbpwd",PWD);

            root.put("isEditor",isEditor);
            root.put("isCategory",isCategory);
            root.put("isUpload",isUpload);

            Template temp = cfg.getTemplate(template);

            // 指定最终渲染的页面存储的位置
            File rootPath = new File(projectPath, packagename);
            if (!rootPath.exists()) rootPath.mkdirs();
            File pojo = new File(rootPath, filename);
            Writer out = new OutputStreamWriter(new FileOutputStream(pojo), StandardCharsets.UTF_8);
            // freemaker的模板渲染替换
            temp.process(root, out);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    private static String replaceLine(String content) {
        return content.replaceAll("\\.", "/");
    }

    public static Connection getMySQLConnection() throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://" + IP + "/" + DB + "?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull", UNAME, PWD);
        return connection;
    }

    public static List<Map<String, String>> loadTable() {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            conn = getMySQLConnection();
            stmt = conn.createStatement();
            String sql = "SELECT * FROM " + tablename;
            rs = stmt.executeQuery(sql);
            ResultSetMetaData rsmd = rs.getMetaData();
            List<Map<String, String>> maps = new ArrayList<>();
            Map<String, String> columnCommentByTableName = getColumnCommentByTableName(tablename);
            for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                String field = rsmd.getColumnName(i);
                int type = rsmd.getColumnType(i);
                String strtype = JDBCTypesUtils.jdbcTypeToJavaType(type).getName();
                Map<String, String> map = new HashMap<>();
                map.put("column", field);//数据库原有的名字
                map.put("name", Tool.lineToHump(field));//小写名字，
                map.put("hname", Tool.HlineToHump(field));//大写的名字，服务于set get
                map.put("type", strtype);//字段对应的java类型
                map.put("comment", columnCommentByTableName.get(field));
                map.put("dtype", JDBCTypesUtils.getJdbcName(type));//字段对应的java类型
                map.put("ctype", strtype.substring(strtype.lastIndexOf(".") + 1));//没有包的类型名字
                maps.add(map);
            }
            return maps;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

}


